<template>
    <div class="slider" ref="slider">
        <div class="slider-group" ref="sliderGroup">
            <slot>
            </slot>
        </div>
        <div class="dots">
            <span class="dot" :class="{active: currentPageIndex === index }" v-for="(item, index) in dots"></span>
        </div>
    </div>
</template>

<script>
    import {addClass} from '../common/js/dom'
    import BScroll from 'better-scroll'
    export default {
        name: 'slider',
        props: {
            loop: {
                type: Boolean,
                default: true
            },
            autoPlay: {
                type: Boolean,
                default: true
            },
            interval: {
                type: Number,
                default: 3000
            }
        },
        data() {
            return {
                dots: [],
                currentPageIndex: 0
            }
        },
        mounted() {
            setTimeout(() => {
                this._setSliderWidth();
                this._initDots();
                this._initSlider();

                if (this.autoPlay) {
                    this._play()
                }
            }, 20);

            window.addEventListener('resize', () => {
                if (!this.slider || !this.slider.enabled) {
                    return
                }
                clearTimeout(this.resizeTimer);
                this.resizeTimer = setTimeout(() => {
                    if (this.slider.isInTransition) {
                        this._onScrollEnd()
                    } else {
                        if (this.autoPlay) {
                            this._play()
                        }
                    }
                    this.refresh()
                }, 60)
            })
        },
        activated() {
            this.slider.enable();
            let pageIndex = this.slider.getCurrentPage().pageX;
            this.slider.goToPage(pageIndex, 0, 0);
            this.currentPageIndex = pageIndex;
            if (this.autoPlay) {
                this._play()
            }
        },
        deactivated() {
            this.slider.disable();
            clearTimeout(this.timer)
        },
        beforeDestroy() {
            this.slider.disable();
            clearTimeout(this.timer)
        },
        methods: {
            refresh() {
                if (this.slider) {
                    this._setSliderWidth(true)
                    this.slider.refresh()
                }
            },
            _setSliderWidth(isResize) {
                this.children = this.$refs.sliderGroup.children;

                let width = 0;
                let sliderWidth = this.$refs.slider.clientWidth;
                for (let i = 0; i < this.children.length; i++) {
                    let child = this.children[i];
                    addClass(child, 'slider-item');

                    child.style.width = sliderWidth + 'px';
                    width += sliderWidth
                }
                if (this.loop && !isResize) {
                    width += 2 * sliderWidth;
                }
                this.$refs.sliderGroup.style.width = width + 'px'
            },
            _initSlider() {
                this.slider = new BScroll(this.$refs.slider, {
                    scrollX: true,
                    scrollY: false,
                    momentum: false,
                    snap: {
                        loop: this.loop,
                        threshold: 0.3,
                        speed: 400
                    }
                });

                this.slider.on('scrollEnd', this._onScrollEnd)

                this.slider.on('touchend', () => {
                    if (this.autoPlay) {
                        this._play()
                    }
                })

                this.slider.on('beforeScrollStart', () => {
                    if (this.autoPlay) {
                        clearTimeout(this.timer)
                    }
                })
            },
            _onScrollEnd() {
                let pageIndex = this.slider.getCurrentPage().pageX
                this.currentPageIndex = pageIndex
                if (this.autoPlay) {
                    this._play()
                }
            },
            _initDots() {
                this.dots = new Array(this.children.length)
            },
            _play() {
                clearTimeout(this.timer)
                this.timer = setTimeout(() => {
                    this.slider.next()
                }, this.interval)
            }
        }
    }
</script>

<style scoped>
    .slider{
        min-height: 1px;
    }
    .slider-group{
        position: relative;
        overflow: hidden;
        white-space: nowrap;
    }
    .slider-group .slider-item{
        float: left;
        box-sizing: border-box;
        overflow: hidden;
        text-align: center;
    }
    .slider-item a{
        display: block;
        width: 100%;
        overflow: hidden;
        text-decoration: none;
    }
    .slider-item img{
        display: block;
        width: 100%;
    }
    .dots{
        position: absolute;
        right: 0;
        left: 0;
        bottom: 12px;
        transform: translateZ(1px);
        text-align: center;
        font-size: 0;
    }
    .dot{
        display: inline-block;
        margin: 0 4px;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: rgba(255, 255, 255, 0.5);
    }
    .dots .active{
        width: 20px;
        border-radius: 5px;
        background: rgba(255, 255, 255, 0.8);
    }
</style>